package com.mzj.saas.mservice.smartlock.service.haixiaoke;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.HexUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.haixiaoke.saas.repository.pojo.SmartLock;
import com.haixiaoke.saas.repository.service.ISmartLockService;
import com.mzj.saas.mservice.lock.entity.LockOpenLog;
import com.mzj.saas.mservice.lock.entity.SmartLockAuth;
import com.mzj.saas.mservice.lock.service.LockOpenLogService;
import com.mzj.saas.mservice.smartlock.vo.haixiaoke.HxkCallBack;
import com.mzj.saas.mservice.smartlock.vo.haixiaoke.LockLoginCallBack;
import com.mzj.saas.mservice.smartlock.vo.haixiaoke.OpenCallBack;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Author Dell
 * @Date 2023/10/8
 **/
@Slf4j
@Service
public class SmartLockHxkCallBackService {

    private static final String authSql = "SELECT a.id,a.user_name as userName  FROM saas_smart_lock_auth a "
            + "LEFT  JOIN  saas_smart_lock_pwd p ON a.id = p.lock_auth_id \n"
            + "WHERE p.identification = ?";

    private static final String cardSql = "SELECT a.id,a.user_name AS userName FROM saas_smart_lock_auth a LEFT JOIN "
            + "saas_smart_lock_card c ON a.id = c.lock_auth_id WHERE c.identification  = ?";

    private static final String faceSql = "SELECT a.id,a.user_name AS userName FROM saas_smart_lock_auth a LEFT JOIN "
            + "saas_smart_lock_face f ON a.id = f.lock_auth_id WHERE  f.identification = ?";

    @Autowired
    private SmartLockHxkEventHandleService smartLockHxkEventHandleService;
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Autowired
    private LockOpenLogService lockOpenLogService;
    @Autowired
    private ISmartLockService iSmartLockService;

    public Map<String, Object> openCallBack(HxkCallBack openCallBack) {
        log.info("嗨小克开门回调参数：{}", JSONObject.toJSONString(openCallBack));
        Map<String,Object> result = new HashMap<>();
        result.put("code",0);
        result.put("msg","操作成功");
        try {
            for (OpenCallBack deviceOpenRecord : openCallBack.getDeviceOpenRecords()) {
                String deviceMac = deviceOpenRecord.getDeviceMac();
                List<SmartLock> smartLocks = iSmartLockService.selectBySns(Arrays.asList(deviceMac));
                if (CollectionUtil.isEmpty(smartLocks)) {
                    log.info("当前回调数据查询不到设备");
                    continue;
                }
                SmartLock smartLock =smartLocks.get(0);
                LockOpenLog openLog = new LockOpenLog();
                switch (deviceOpenRecord.getOpenType()){
                    case "01"://人脸开门
                        openLog.setLockId(smartLock.getId());
                        openLog.setHouseId(smartLock.getHouseId());
                        openLog.setOpenMode(32);
                        openLog.setOpenType(1);// 开门类型：0未知 1外开门 2内开门
                        openLog.setBuildName(smartLock.getBuildName());
                        openLog.setCommunityName(smartLock.getCommunityName());
                        openLog.setUnitName(smartLock.getUnitName());
                        openLog.setMatchUserName(smartLock.getMatchUserName());
                        openLog.setRoomNumber(smartLock.getRoomNumber());
                        openLog.setOpenTime(DateUtil.parse(deviceOpenRecord.getOpenTime()));
                        openLog.setUserProperty(0);// 开门人性质：0未知 1承租人 2同住人
                        List<SmartLockAuth> smartLockAuth3 = jdbcTemplate.query(faceSql, new BeanPropertyRowMapper<>(SmartLockAuth.class), deviceOpenRecord.getIdNumber());
                        if (CollectionUtil.isNotEmpty(smartLockAuth3)) {
                            openLog.setUserId(smartLockAuth3.get(0).getId());
                            openLog.setOpenUserName(smartLockAuth3.get(0).getUserName());//开门人姓名
                            lockOpenLogService.save(openLog);
                        }
                    case "02":
                        break;
                    case "04"://卡开门
                        openLog.setLockId(smartLock.getId());
                        openLog.setHouseId(smartLock.getHouseId());
                        openLog.setOpenMode(11);
                        openLog.setOpenType(1);// 开门类型：0未知 1外开门 2内开门
                        openLog.setBuildName(smartLock.getBuildName());
                        openLog.setCommunityName(smartLock.getCommunityName());
                        openLog.setUnitName(smartLock.getUnitName());
                        openLog.setMatchUserName(smartLock.getMatchUserName());
                        openLog.setRoomNumber(smartLock.getRoomNumber());
                        openLog.setOpenTime(DateUtil.parse(deviceOpenRecord.getOpenTime()));
                        openLog.setUserProperty(0);// 开门人性质：0未知 1承租人 2同住人
                        List<SmartLockAuth> smartLockAuth2 = jdbcTemplate.query(cardSql, new BeanPropertyRowMapper<>(SmartLockAuth.class), deviceOpenRecord.getIdNumber());
                        if (CollectionUtil.isNotEmpty(smartLockAuth2)) {
                            openLog.setUserId(smartLockAuth2.get(0).getId());
                            openLog.setOpenUserName(smartLockAuth2.get(0).getUserName());//开门人姓名
                            lockOpenLogService.save(openLog);
                        }
                    case "03"://密码开门
                        openLog.setLockId(smartLock.getId());
                        openLog.setHouseId(smartLock.getHouseId());
                        openLog.setOpenMode(0);
                        openLog.setOpenType(1);// 开门类型：0未知 1外开门 2内开门
                        openLog.setBuildName(smartLock.getBuildName());
                        openLog.setCommunityName(smartLock.getCommunityName());
                        openLog.setUnitName(smartLock.getUnitName());
                        openLog.setMatchUserName(smartLock.getMatchUserName());
                        openLog.setRoomNumber(smartLock.getRoomNumber());
                        openLog.setOpenTime(DateUtil.parse(deviceOpenRecord.getOpenTime()));
                        openLog.setUserProperty(0);// 开门人性质：0未知 1承租人 2同住人
                        List<SmartLockAuth> smartLockAuth1 = jdbcTemplate.query(authSql, new BeanPropertyRowMapper<>(SmartLockAuth.class), deviceOpenRecord.getIdNumber());
                        if (CollectionUtil.isNotEmpty(smartLockAuth1)) {
                            openLog.setUserId(smartLockAuth1.get(0).getId());
                            openLog.setOpenUserName(smartLockAuth1.get(0).getUserName());//开门人姓名
                            lockOpenLogService.save(openLog);
                        }
                    case "05"://临时密码
                        break;
                    case "06":
                        break;//远程开门
                }
            }
        } catch (Exception e) {
            result.put("code",1);
            result.put("msg","操作失败");
            log.error("嗨小克, 开门回调异常：", e);
        }
        return result;
    }

    public Map<String, Object> devices(HxkCallBack hxkCallBack) {
        log.info("嗨小克上线回调参数：{}", JSONObject.toJSONString(hxkCallBack));
        Map<String,Object> result = new HashMap<>();
        result.put("code",0);
        result.put("msg","操作成功");
        try {
            List<LockLoginCallBack> devices = hxkCallBack.getDevices();
            List<String> macList = devices.stream().map(LockLoginCallBack::getDeviceMac).collect(Collectors.toList());
            Map<String, LockLoginCallBack> collect = devices.stream().collect(Collectors.toMap(LockLoginCallBack::getDeviceMac, a -> a));
            List<SmartLock> smartLocks = iSmartLockService.selectBySns(macList);
            if (CollUtil.isNotEmpty(smartLocks)) {
                for (SmartLock smartLock : smartLocks) {
                    LockLoginCallBack lockLoginCallBack = collect.get(smartLock.getSn());
                    if (ObjectUtil.isNotEmpty(lockLoginCallBack)) {
                        smartLock.setElectricQuantity(Integer.parseInt(lockLoginCallBack.getBatteryPercent()));
                        DateTime date = DateUtil.parse(lockLoginCallBack.getLoginTime(), "yyyy-MM-dd");
                        DateTime nowTime = DateUtil.parse(DateUtil.now(), "yyyy-MM-dd");
                        int compareTo = nowTime.compareTo(date);
                        if (compareTo == 0) {
                            smartLock.setOnlineStatus(1);
                        } else {
                            smartLock.setOnlineStatus(0);
                        }
                    }
                }
                iSmartLockService.updateBatchById(smartLocks);
            }
        }catch (Exception e){
            result.put("code",1);
            result.put("msg","操作失败");
            log.error("嗨小克, 设备上线回调异常：", e);
        }
        return result;
    }

    public Map<String, Object> deleteAuth(SmartLock smartLock,String authorization) {
        log.info("嗨小克删除授权用户参数：{}", JSONObject.toJSONString(smartLock));
        String decrypt = this.decrypt(authorization);
        Map<String,Object> result = new HashMap<>();
        if (!"admin".equals(decrypt)) {
            result.put("code",1);
            result.put("msg","操作失败");
            log.error("解密的认证信息异常！");
            return result;
        }
        if (StrUtil.isEmpty(smartLock.getSn())) {
            result.put("code",1);
            result.put("msg","缺少设备mac");
            return result;
        } else {
            return smartLockHxkEventHandleService.deleteAuth(smartLock.getSn());
        }
    }

    /**
     * 解密
     * @param str
     * @return
     */
    public String decrypt(String str){
        try {
            byte[] raw = "e75e2d3126357d031ddaf412f9110f66".getBytes(StandardCharsets.UTF_8);
            SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, skeySpec);
            byte[] ss = HexUtil.decodeHex(str);
            byte[] original = cipher.doFinal(ss);
            String originalString = new String(original, StandardCharsets.UTF_8);
            log.info("嗨小克--删除授权用户业务数据解密后参数：{}",originalString);
            return originalString;
        } catch (Exception e) {
            log.error("嗨小克--删除授权用户业务数据解密异常：{}",e.getMessage(),e);
        }
        return null;
    }
}
